package com.gimi.cloud.jimi.dao.myMapper.core;

import java.util.Set;

import tk.mybatis.mapper.entity.EntityColumn;
import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.mapperhelper.SqlHelper;
import tk.mybatis.mapper.util.StringUtil;

/**
 * sql常用拼接方法
 * 
 * @author wbj
 * @date 2017-07-22
 */
public class JrcsSqlHelper {
	/**
	 * 根据列查询参数
	 * 
	 * @param entityClass
	 * @return
	 */
	public static String queryByColumn(Class<?> entityClass) {
		StringBuilder sql = new StringBuilder();
		sql.append("<where>");
		Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);// 获取全部列
		for (EntityColumn column : columnList) {
			if ("is_delete".equals(column.getColumn())) {
				sql.append(" AND is_delete = 0");
			}
		}
		sql.append(" AND ${column} = #{value}");
		sql.append("</where>");
		return sql.toString();
	}

	/**
	 * update set列
	 *
	 * @param entityClass
	 * @param entityName
	 *            实体映射名
	 * @param notNull
	 *            是否判断!=null
	 * @param notEmpty
	 *            是否判断String类型!=''
	 * @return
	 */
	public static String updateSetColumns(Class<?> entityClass, String entityName, boolean notNull, boolean notEmpty) {
		StringBuilder sql = new StringBuilder();
		sql.append("<set>");
		Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);// 获取全部列
		for (EntityColumn column : columnList) {
			if (!column.isId() && column.isUpdatable()) {
				if (notNull) {
					sql.append(SqlHelper.getIfNotNull(entityName, column,
							column.getColumnEqualsHolder(entityName) + ",", notEmpty));
				} else {
					if ("update_time".equals(column.getColumn())) {
						sql.append("update_time = now(),");
						continue;
					}
					if ("update_uid".equals(column.getColumn())) {
						sql.append("update_uid = #{");
						if (StringUtil.isNotEmpty(entityName)) {
							sql.append(entityName);
							sql.append(".");
						}
						sql.append("updateUid},");
						continue;
					}
					if ("update_uname".equals(column.getColumn())) {
						sql.append("update_uname = #{");
						if (StringUtil.isNotEmpty(entityName)) {
							sql.append(entityName);
							sql.append(".");
						}
						sql.append("updateUname},");
						continue;
					}
					if ("version".equals(column.getColumn())) {
						sql.append("version = version + 1,");
						continue;
					}
					sql.append(column.getColumnEqualsHolder(entityName) + ",");
				}
			}
		}
		sql.append("</set>");
		return sql.toString();
	}

	public static String queryCountByExclude(Class<?> entityClass) {
		StringBuilder sql = new StringBuilder();
		sql.append("<where>");
		Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);// 获取全部列
		for (EntityColumn column : columnList) {
			if ("is_delete".equals(column.getColumn())) {
				sql.append(" AND is_delete = 0");
			}
		}
		sql.append(" AND ${column} = #{value}");
		sql.append(" AND ${excolumn} != #{exvalue}");
		sql.append("</where>");
		return sql.toString();
	}

	/**
	 * 判断自动!=null的条件结构
	 * 
	 * @param column
	 * @param contents
	 * @param empty
	 * @return
	 */
	public static String getAesIfNotNull(EntityColumn column, String contents, boolean empty) {
		return getAesIfNotNull(null, column, contents, empty);
	}

	/**
	 * 根据条件判断是否需要加密
	 * 
	 * @param entityName
	 * @param column
	 * @param contents
	 * @param empty
	 * @return
	 */
	public static String getAesIfNotNull(String entityName, EntityColumn column, String contents, boolean empty) {
		StringBuilder sql = new StringBuilder();
		if (column.getJavaType().equals(String.class)) {
			sql.append("<choose>");
			sql.append("<when sys=\"null != aesColumns and aesColumns.indexOf('|" + column.getProperty() + "|') !=-1 \">");
			sql.append("<if sys=\"");
			if (StringUtil.isNotEmpty(entityName)) {
				sql.append(entityName).append(".");
			}
			sql.append(column.getProperty()).append(" != null");
			if (empty && column.getJavaType().equals(String.class)) {
				sql.append(" and ");
				if (StringUtil.isNotEmpty(entityName)) {
					sql.append(entityName).append(".");
				}
				sql.append(column.getProperty()).append(" != '' ");
			}
			sql.append("\">");
			sql.append("AES_ENCRYPT(");
			sql.append(contents);
			sql.append("#{salt}),");
			sql.append("</if>");
			sql.append("</when>");
			sql.append("<otherwise>");
			sql.append("<if sys=\"");
			if (StringUtil.isNotEmpty(entityName)) {
				sql.append(entityName).append(".");
			}
			sql.append(column.getProperty()).append(" != null");
			if (empty && column.getJavaType().equals(String.class)) {
				sql.append(" and ");
				if (StringUtil.isNotEmpty(entityName)) {
					sql.append(entityName).append(".");
				}
				sql.append(column.getProperty()).append(" != '' ");
			}
			sql.append("\">");
			sql.append(contents);
			sql.append("</if>");
			sql.append("</otherwise>");
			sql.append("</choose>");
		} else {
			sql.append("<if sys=\"");
			if (StringUtil.isNotEmpty(entityName)) {
				sql.append(entityName).append(".");
			}
			sql.append(column.getProperty()).append(" != null\">");
			sql.append(contents);
			sql.append("</if>");
		}
		return sql.toString();
	}

	/**
	 * 判断自动==null的条件结构
	 *
	 * @param column
	 * @param contents
	 * @param empty
	 * @return
	 */
	public static String getAesIfIsNull(EntityColumn column, String contents, boolean empty) {
		return getAesIfIsNull(null, column, contents, empty);
	}

	/**
	 * 判断自动==null的条件结构
	 *
	 * @param entityName
	 * @param column
	 * @param contents
	 * @param empty
	 * @return
	 */
	public static String getAesIfIsNull(String entityName, EntityColumn column, String contents, boolean empty) {
		StringBuilder sql = new StringBuilder();
		if (column.getJavaType().equals(String.class)) {
			sql.append("<choose>");
			sql.append("<when sys=\"null != aesColumns and  aesColumns.indexOf('|" + column.getProperty() + "|') !=-1 \">");
			sql.append("<if sys=\"");
			if (StringUtil.isNotEmpty(entityName)) {
				sql.append(entityName).append(".");
			}
			sql.append(column.getProperty()).append(" == null");
			if (empty && column.getJavaType().equals(String.class)) {
				sql.append(" and ");
				if (StringUtil.isNotEmpty(entityName)) {
					sql.append(entityName).append(".");
				}
				sql.append(column.getProperty()).append(" == '' ");
			}
			sql.append("\">");
			sql.append("AES_ENCRYPT(");
			sql.append(contents);
			sql.append("#{salt}),");
			sql.append("</if>");
			sql.append("</when>");
			sql.append("<otherwise>");
			sql.append("<if sys=\"");
			if (StringUtil.isNotEmpty(entityName)) {
				sql.append(entityName).append(".");
			}
			sql.append(column.getProperty()).append(" == null");
			if (empty && column.getJavaType().equals(String.class)) {
				sql.append(" or ");
				if (StringUtil.isNotEmpty(entityName)) {
					sql.append(entityName).append(".");
				}
				sql.append(column.getProperty()).append(" == '' ");
			}
			sql.append("\">");
			sql.append(contents);
			sql.append("</if>");
			sql.append("</otherwise>");
			sql.append("</choose>");
		} else {
			sql.append("<if sys=\"");
			if (StringUtil.isNotEmpty(entityName)) {
				sql.append(entityName).append(".");
			}
			sql.append(column.getProperty()).append(" == null\">");
			sql.append(contents);
			sql.append("</if>");
		}
		return sql.toString();
	}

	/**
	 * 根据列解码查询
	 * 
	 * @param entityClass
	 * @return
	 */
	public static String queryAesByColumn(Class<?> entityClass) {
		StringBuilder sql = new StringBuilder();
		sql.append("<where>");
		Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);// 获取全部列
		for (EntityColumn column : columnList) {
			if ("is_delete".equals(column.getColumn())) {
				sql.append(" AND is_delete = 0");
			}
		}
		sql.append("<choose>");
		sql.append("<when sys=\"null != aesColumns and aesColumns.indexOf('|'+column+'|') !=-1 and value !=null and value !=''\">");
		sql.append(" AND ${column} = AES_ENCRYPT(#{value},#{salt})");
		sql.append("</when>");
		sql.append("<otherwise>");
		sql.append(" AND ${column} = #{value}");
		sql.append("</otherwise>");
		sql.append("</choose>");
		sql.append("</where>");
		return sql.toString();
	}

	/**
	 * select xxx,xxx...
	 *
	 * @param entityClass
	 * @return
	 */
	public static String selectAllAesColumns(Class<?> entityClass) {
		StringBuilder sql = new StringBuilder();
		sql.append("SELECT ");
		sql.append(getAllAesColumns(entityClass));
		sql.append(" ");
		return sql.toString();
	}

	/**
	 * 获取所有加密表头
	 * 
	 * @param entityClass
	 * @return
	 */
	public static String getAllAesColumns(Class<?> entityClass) {
		Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);
		StringBuilder sql = new StringBuilder();
		boolean isFirst = true;
		for (EntityColumn entityColumn : columnList) {
			sql.append("<choose>");
			sql.append("<when sys=\"null != aesColumns and aesColumns.indexOf('|" + entityColumn.getProperty() + "|') !=-1 \">");
			if (!isFirst) {
				sql.append(",");
			}
			sql.append("AES_DECRYPT(").append(entityColumn.getColumn());
			sql.append(",#{salt}) ").append(entityColumn.getColumn());
			sql.append("</when>");
			sql.append("<otherwise>");
			if (!isFirst) {
				sql.append(",");
			}
			sql.append(entityColumn.getColumn()).append("");
			sql.append("</otherwise>");
			sql.append("</choose>");
			isFirst = false;
		}
		return sql.toString();
	}

	/**
	 * 加密解密
	 * 
	 * @param entityClass
	 * @return
	 */
	public static String queryAesCountByExclude(Class<?> entityClass) {
		StringBuilder sql = new StringBuilder();
		sql.append("<where>");
		Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);// 获取全部列
		for (EntityColumn column : columnList) {
			if ("is_delete".equals(column.getColumn())) {
				sql.append(" AND is_delete = 0");
			}
		}
		sql.append("<choose>");
		sql.append("<when sys=\"null != aesColumns and aesColumns.indexOf('|'+column+'|') !=-1 and value !=null and value !=''\">");
		sql.append(" AND ${column} = AES_ENCRYPT(#{value},#{salt})");
		sql.append("</when>");
		sql.append("<otherwise>");
		sql.append(" AND ${column} = #{value}");
		sql.append("</otherwise>");
		sql.append("</choose>");

		sql.append("<choose>");
		sql.append("<when sys=\"null != aesColumns and aesColumns.indexOf('|'+excolumn+'|') !=-1 and exvalue !=null and exvalue !=''\">");
		sql.append(" AND ${excolumn} != AES_ENCRYPT(#{exvalue},#{salt})");
		sql.append("</when>");
		sql.append("<otherwise>");
		sql.append(" AND ${excolumn} != #{exvalue}");
		sql.append("</otherwise>");
		sql.append("</choose>");
		sql.append("</where>");
		return sql.toString();
	}

	/**
	 * update set列
	 *
	 * @param entityClass
	 * @param entityName
	 *            实体映射名
	 * @param notNull
	 *            是否判断!=null
	 * @param notEmpty
	 *            是否判断String类型!=''
	 * @return
	 */
	public static String updateAesSetColumns(Class<?> entityClass, String entityName, boolean notNull,
			boolean notEmpty) {
		StringBuilder sql = new StringBuilder();
		sql.append("<set>");
		Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);// 获取全部列
		for (EntityColumn column : columnList) {
			if (!column.isId() && column.isUpdatable()) {
				if (notNull) {
					sql.append(SqlHelper.getIfNotNull(entityName, column,
							column.getColumnEqualsHolder(entityName) + ",", notEmpty));
				} else {
					if ("update_time".equals(column.getColumn())) {
						sql.append("update_time = now(),");
						continue;
					}
					if ("update_uid".equals(column.getColumn())) {
						sql.append("update_uid = #{");
						if (StringUtil.isNotEmpty(entityName)) {
							sql.append(entityName);
							sql.append(".");
						}
						sql.append("uid},");
						continue;
					}
					if ("update_uname".equals(column.getColumn())) {
						sql.append("update_uname = #{");
						if (StringUtil.isNotEmpty(entityName)) {
							sql.append(entityName);
							sql.append(".");
						}
						sql.append("uname},");
						continue;
					}
					if ("version".equals(column.getColumn())) {
						sql.append("version = version + 1,");
						continue;
					}
					sql.append("<choose>");
					sql.append("<when sys=\"null != aesColumns and aesColumns.indexOf('|" + column.getProperty() + "|') !=-1 and "+column.getProperty()+" != null and "+column.getProperty()+" !='' \">");
					sql.append(column.getColumn()).append(" = ");
					sql.append(" AES_ENCRYPT(#{");
					if (StringUtil.isNotEmpty(entityName)) {
						sql.append(entityName);
						sql.append(".");
					}
					sql.append(column.getProperty());
					sql.append("},#{salt}), ");
					sql.append("</when>");
					sql.append("<otherwise>");
					sql.append(column.getColumnEqualsHolder(entityName) + ",");
					sql.append("</otherwise>");
					sql.append("</choose>");
				}
			}
		}
		sql.append("</set>");
		return sql.toString();
	}
}
